home *** CD-ROM | disk | FTP | other *** search
/ Computer Inter@ctive 16 / Computer Interactive cdrom 16 - dic 98.iso / zdnetit / content / CMATHCC.ZIP / INCLUDE.ZIP / CDMATH.H next >
Encoding:
C/C++ Source or Header  |  1998-09-01  |  14.5 KB  |  448 lines

  1. /*    CDMATH.H
  2.  
  3.       Complex library for the languages C and C++.
  4.  
  5.       This header file contains all definitions for
  6.       double-precision complex numbers (complex double).
  7.  
  8.       Copyright (C) 1996-1998 Martin Sander
  9.       Address of the author:
  10.            Martin Sander
  11.            Sertⁿrnerstr. 11
  12.            D-37085 G÷ttingen
  13.            Germany
  14.  
  15. */
  16.  
  17.  
  18. #ifndef __CDMATH_H
  19. #define __CDMATH_H
  20.  
  21. #if !defined( _CMATH_DEFS )
  22.    #ifdef __BORLANDC__
  23.        #pragma option -a-
  24.    #else /* Visual C++, Optima++ */
  25.        #pragma pack( push,1 )
  26.    #endif /* avoid insertion of dummy bytes  */
  27.    typedef struct {float    Re, Im;} fComplex;
  28.    typedef struct {double   Re, Im;} dComplex;
  29.    #ifdef __BORLANDC__
  30.        typedef long double    extended;
  31.        typedef struct {extended Re, Im;} eComplex;
  32.        #pragma option -a.
  33.    #else /* Visual C++, Optima++ */
  34.        typedef  double extended; /* Visual C++ does not support
  35.                                  80-bit IEEE numbers. So make
  36.                                  extended equal to double    */
  37.        typedef dComplex  eComplex;
  38.        #pragma pack( pop )
  39.    #endif    /* restore default data packing  */
  40.    typedef fComplex fcomplex;
  41.    typedef dComplex dcomplex;
  42.    typedef eComplex ecomplex;  // tolerate all-minuscule
  43.    #define _CMATH_DEFS
  44. #endif
  45. #ifdef __BORLANDC__
  46.     #include <_defs.h>
  47.     #if defined __SMALL__ || defined __MEDIUM__
  48.          #define   _VFAR  near   /* even in case of DS!=SS  */
  49.     #elif defined __FLAT__
  50.          #define  _VFAR
  51.     #else
  52.          #define   _VFAR  far
  53.     #endif
  54.     #if (__BORLANDC__ >= 0x450)
  55.          #define __cmf _RTLENTRY _EXPFUNC
  56.     #else
  57.          #define __cmf  _Cdecl _FARFUNC
  58.     #endif
  59. #else  /* Visual C++, Optima++ */
  60.     #define _VFAR
  61.     #define __cmf  __cdecl
  62. #endif
  63.  
  64. /*  first the constructors:  */
  65. #ifdef __cplusplus
  66.    /* since dComplex is declared as a struct instead of a class,
  67.       the constructor cannot get the name "dComplex" here.     */
  68.   #ifndef _DCPLX_DEFINED
  69.   inline dComplex __cmf dcplx( double __ReVal )
  70.   {   dComplex Result;
  71.       Result.Re = __ReVal;
  72.       Result.Im = 0.0;
  73.       return Result;
  74.   }
  75.  
  76.       // up-conversions from single precision
  77.   inline dComplex __cmf dcplx( fComplex & __zf )
  78.   {   dComplex Result;
  79.       Result.Re = __zf.Re;
  80.       Result.Im = __zf.Im;
  81.       return Result;
  82.   }
  83.       // down-conversion from extended precision
  84.       // (with OVERFLOW error handling):
  85.   #ifdef __BORLANDC__
  86.       dComplex __cmf dcplx( eComplex __ze );
  87.   #else
  88.       inline dComplex & __cmf dcplx( dComplex & __zd )
  89.       {   return __zd;  }  // necessary because eComplex=dComplex
  90.   #endif
  91.   #define _DCPLX_DEFINED
  92.   #endif  // _DCPLX_DEFINED
  93. extern "C" {
  94. #endif   /* basic form of constructor for C and C++ : */
  95.    dComplex __cmf dcplx( double __ReVal, double __ImVal);
  96.          /* conversion from fComplex and eComplex (with OVERFLOW handling) */
  97. #if !defined __NEWCPLX_H
  98.    dComplex __cmf cftocd( fComplex __zf );
  99.    dComplex __cmf cetocd( eComplex __ze );
  100. #endif
  101.  
  102.    /* Basic complex operations. They are defined both
  103.    for C and C++. However, for C++ you may as well use the
  104.    overloaded operators and functions defined further below. */
  105. #define         cd_real( z )  (z).Re
  106. #define         cd_imag( z )  (z).Im
  107. dComplex __cmf  cd_neg(  dComplex __z );
  108. dComplex __cmf  cd_conj( dComplex __z );
  109. double   __cmf  cd_norm( dComplex __z );
  110. double   __cmf  cd_arg(  dComplex __z );
  111. dComplex __cmf  cd_polar( double __mag, double __angle );
  112.  
  113. dComplex __cmf  cd_add(   dComplex __x, dComplex __y );
  114. dComplex __cmf  cd_addRe( dComplex __x, double __yRe );
  115. dComplex __cmf  cd_sub(   dComplex __x, dComplex __y );
  116. dComplex __cmf  cd_subRe( dComplex __x, double __yRe );  /*  x - yRe  */
  117. dComplex __cmf  cd_subrRe( dComplex __x, double __yRe ); /*  yRe - x  */
  118. dComplex __cmf  cd_mul(   dComplex __x, dComplex __y );
  119. dComplex __cmf  cd_mulRe( dComplex __x, double __yRe );
  120. dComplex __cmf  cd_div(   dComplex __x, dComplex __y );
  121. dComplex __cmf  cd_divRe( dComplex __x, double __yRe );   /*  x / yRe  */
  122. dComplex __cmf  cd_divrRe( dComplex __x, double __yRe );  /*  yRe / x  */
  123.  
  124. /*  mathematical functions with error handling through _matherr: */
  125. double   __cmf  cd_abs(  dComplex __z );
  126. dComplex __cmf  cd_acos( dComplex __z );
  127. dComplex __cmf  cd_asin( dComplex __z );
  128. dComplex __cmf  cd_atan( dComplex __z );
  129. dComplex __cmf  cd_cos(  dComplex __z );
  130. dComplex __cmf  cd_cosh( dComplex __z );
  131. dComplex __cmf  cd_cubic( dComplex __z );  /* raise to the third power */
  132. dComplex __cmf  cd_exp(  dComplex __z );
  133. dComplex __cmf  cd_inv(  dComplex __z );    /*   1.0 / z   */
  134. dComplex __cmf  cd_ipow( dComplex __z, int __exponent );
  135.                                              /* raise z to integer power */
  136. dComplex __cmf  cd_ln(   dComplex __z );
  137. dComplex __cmf  cd_log(   dComplex __z );  /* sane as cd_ln */
  138. dComplex __cmf  cd_log2(  dComplex __z );
  139. dComplex __cmf  cd_log10( dComplex __z );
  140. dComplex __cmf  cd_pow( dComplex __base, dComplex __exponent );
  141. dComplex __cmf  cd_powReBase( double __base, dComplex __exponent ); /* power of real base */
  142. dComplex __cmf  cd_powReExpo( dComplex __base, double __exponent ); /* raise z to real power */
  143.                          /* for integer exponents, use cd_ipow ! */
  144. dComplex __cmf  cd_quartic( dComplex __z );  /* raise to the fourth power */
  145. dComplex __cmf  cd_sin(  dComplex __z );
  146. dComplex __cmf  cd_sinh( dComplex __z );
  147. dComplex __cmf  cd_square( dComplex __z );
  148. dComplex __cmf  cd_sqrt( dComplex __z );
  149. dComplex __cmf  cd_tan(  dComplex __z );
  150. dComplex __cmf  cd_tanh( dComplex __z );
  151.  
  152.  
  153. #ifdef __cplusplus
  154. }    //  end of the extern "C" statement
  155.  
  156. #if !defined __STD_COMPLEX && !defined __COMPLEX_H && !defined __NEWCPLX_H
  157.    /* in addition to the basic operations defined above for C,
  158.       here is the same complete set of overloaded operators and
  159.       functions as offered by the class complex of C++ compilers.     */
  160.  
  161.     inline double real( dComplex & __z )
  162.     {
  163.         return __z.Re;
  164.     }
  165.  
  166.     inline double imag( dComplex & __z )
  167.     {
  168.         return __z.Im;
  169.     }
  170.  
  171.     inline dComplex neg( dComplex & __z1 )
  172.     {   dComplex Result;
  173.         Result.Re = -__z1.Re;
  174.         Result.Im = -__z1.Im;
  175.         return Result;
  176.     }
  177.  
  178.     inline dComplex conj( dComplex & __z)
  179.     {   dComplex Result;
  180.         Result.Re =  __z.Re;
  181.         Result.Im = -__z.Im;
  182.         return Result;
  183.     }
  184.  
  185.     inline double norm( dComplex & __z )
  186.     {
  187.        return __z.Re * __z.Re + __z.Im * __z.Im;
  188.     }
  189.  
  190.     double   __cmf  arg(  dComplex __z );
  191.     dComplex __cmf  polar( double Mag, double Angle );
  192.  
  193.   //  unary operators:
  194.  
  195.   inline dComplex & operator +( dComplex & __z1 )
  196.   {
  197.       return __z1;
  198.   }
  199.  
  200.   inline dComplex operator -( dComplex & __z1 )
  201.   {   dComplex Result;
  202.       Result.Re = -__z1.Re;
  203.       Result.Im = -__z1.Im;
  204.       return Result;
  205.   }
  206.  
  207.  
  208.   //  binary operators:
  209.  
  210.   inline dComplex operator +( dComplex & __z1, dComplex & __z2 )
  211.   {   dComplex Result;
  212.       Result.Re = __z1.Re + __z2.Re;
  213.       Result.Im = __z1.Im + __z2.Im;
  214.       return Result;
  215.   }
  216.  
  217.   inline dComplex operator +( dComplex & __z1, double __z2Re )
  218.   {   dComplex Result;
  219.       Result.Re = __z1.Re + __z2Re;
  220.       Result.Im = __z1.Im;
  221.       return Result;
  222.   }
  223.  
  224.   inline dComplex operator +( double __z1Re, dComplex & __z2 )
  225.   {   dComplex Result;
  226.       Result.Re = __z1Re + __z2.Re;
  227.       Result.Im = __z2.Im;
  228.       return Result;
  229.   }
  230.  
  231.   inline dComplex operator -( dComplex & __z1, dComplex & __z2 )
  232.   {   dComplex Result;
  233.       Result.Re = __z1.Re - __z2.Re;
  234.       Result.Im = __z1.Im - __z2.Im;
  235.       return Result;
  236.   }
  237.  
  238.   inline dComplex operator -( dComplex & __z1, double __z2Re )
  239.   {   dComplex Result;
  240.       Result.Re = __z1.Re - __z2Re;
  241.       Result.Im = __z1.Im;
  242.       return Result;
  243.   }
  244.  
  245.   inline dComplex operator -( double __z1Re, dComplex & __z2 )
  246.   {   dComplex Result;
  247.       Result.Re = __z1Re - __z2.Re;
  248.       Result.Im = -__z2.Im;
  249.       return Result;
  250.   }
  251.  
  252.   inline dComplex operator *( dComplex & __z1, dComplex & __z2 )
  253.   {   dComplex Result;
  254.       Result.Re  = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  255.       Result.Im  = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  256.       return Result;
  257.   }
  258.  
  259.   inline dComplex operator *( dComplex & __z1, double __z2Re )
  260.   {   dComplex Result;
  261.       Result.Re = __z1.Re * __z2Re;
  262.       Result.Im = __z1.Im * __z2Re;
  263.       return Result;
  264.   }
  265.  
  266.   inline dComplex operator *( double __z1Re, dComplex & __z2 )
  267.   {   dComplex Result;
  268.       Result.Re  = __z1Re * __z2.Re;
  269.       Result.Im  = __z1Re * __z2.Im;
  270.       return Result;
  271.   }
  272.  
  273.   inline dComplex operator /( dComplex & __z1, dComplex & __z2 )
  274.   {   dComplex Result;
  275.       long double denom;
  276.       Result.Re = (__z1.Re * __z2.Re + __z1.Im * __z2.Im) /
  277.         (denom = (long double)(__z2.Re) * __z2.Re + (long double)(__z2.Im) * __z2.Im);
  278.       Result.Im = (__z1.Im * __z2.Re - __z1.Re * __z2.Im ) / denom;
  279.       return Result;
  280.   }
  281.  
  282.   inline dComplex operator /( dComplex & __z1, double __z2Re )
  283.   {   dComplex Result;
  284.       Result.Re = __z1.Re / __z2Re;
  285.       Result.Im = __z1.Im / __z2Re;
  286.       return Result;
  287.   }
  288.  
  289.   inline dComplex operator /( double __z1Re, dComplex & __z2 )
  290.   {   dComplex Result;
  291.       long double denom;
  292.       Result.Re = (__z1Re * __z2.Re) /
  293.         (denom = (long double)(__z2.Re) * __z2.Re + (long double)(__z2.Im) * __z2.Im);
  294.       Result.Im = -(__z1Re * __z2.Im ) / denom;
  295.       return Result;
  296.   }
  297.  
  298.   inline dComplex & operator +=( dComplex & __z1, dComplex & __z2 )
  299.   {
  300.       __z1.Re += __z2.Re;
  301.       __z1.Im += __z2.Im;
  302.       return __z1;
  303.   }
  304.  
  305.   inline dComplex & operator +=( dComplex & __z1, double __z2Re )
  306.   {
  307.       __z1.Re += __z2Re;
  308.       return __z1;
  309.   }
  310.  
  311.   inline dComplex & operator -=( dComplex & __z1, dComplex & __z2 )
  312.   {
  313.       __z1.Re -= __z2.Re;
  314.       __z1.Im -= __z2.Im;
  315.       return __z1;
  316.   }
  317.  
  318.   inline dComplex & operator -=( dComplex & __z1, double __z2Re )
  319.   {
  320.       __z1.Re -= __z2Re;
  321.       return __z1;
  322.   }
  323.  
  324.   inline dComplex & operator *=( dComplex & __z1, dComplex & __z2 )
  325.   {
  326.       double tmpRe;
  327.       tmpRe   = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  328.       __z1.Im = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  329.       __z1.Re = tmpRe;
  330.       return __z1;
  331.   }
  332.  
  333.   inline dComplex & operator *=( dComplex & __z1, double __z2Re )
  334.   {
  335.       __z1.Re *= __z2Re;
  336.       __z1.Im *= __z2Re;
  337.       return __z1;
  338.   }
  339.  
  340.   inline dComplex & operator /=( dComplex & __z1, dComplex & __z2 )
  341.   {   long double denom;
  342.       double      tmpRe;
  343.       tmpRe = (__z1.Re * __z2.Re + __z1.Im * __z2.Im) /
  344.         (denom = (long double)(__z2.Re) * __z2.Re + (long double)(__z2.Im) * __z2.Im);
  345.       __z1.Im = (__z1.Im * __z2.Re - __z1.Re * __z2.Im ) / denom;
  346.       __z1.Re = tmpRe;
  347.       return __z1;
  348.   }
  349.  
  350.   inline dComplex & operator /=( dComplex & __z1, double __z2Re )
  351.   {
  352.       __z1.Re /= __z2Re;
  353.       __z1.Im /= __z2Re;
  354.       return __z1;
  355.   }
  356.  
  357.   inline int operator ==( dComplex & __z1, dComplex & __z2 )
  358.   {
  359.       return (__z1.Re == __z2.Re) && (__z1.Im == __z2.Im );
  360.   }
  361.  
  362.   inline int operator ==( dComplex & __z1, double __z2Re )
  363.   {
  364.       return (__z1.Re == __z2Re) && (__z1.Im == 0.0 );
  365.   }
  366.  
  367.   inline int operator !=( dComplex & __z1, dComplex & __z2 )
  368.   {
  369.       return (__z1.Re != __z2.Re) || (__z1.Im != __z2.Im );
  370.   }
  371.  
  372.   inline int operator !=( dComplex & __z1, double __z2Re )
  373.   {
  374.       return (__z1.Im != 0.0 ) || (__z1.Re != __z2Re);
  375.   }
  376.  
  377.  
  378.   /*  C++ version of the mathematical functions defined above.
  379.       They use the same code as the C versions. In case of an error,
  380.       you get a message in which the name of the C version is
  381.       stated.
  382.       Note that these functions require complex arguments to be
  383.       passed by value, not by reference, as it is done in the member
  384.       functions of the class complex. In terms of efficiency, this
  385.       is about the same. (The math functions of the class complex
  386.       store complex results at intermediate addresses and copy them
  387.       to the desired address afterwards. This final copy is not
  388.       necessary here.)                                             */
  389.  
  390.   double    __cmf  abs(  dComplex __z );
  391.   dComplex __cmf  acos( dComplex __z );
  392.   dComplex __cmf  asin( dComplex __z );
  393.   dComplex __cmf  atan( dComplex __z );
  394.   dComplex __cmf  cos(  dComplex __z );
  395.   dComplex __cmf  cosh( dComplex __z );
  396.   dComplex __cmf  cubic( dComplex __z );  /* raise to the third power */
  397.   dComplex __cmf  exp(  dComplex __z );
  398.   dComplex __cmf  inv(  dComplex __z );    /*   1.0 / z   */
  399.   dComplex __cmf  ipow( dComplex __z, int __exponent );
  400.                                             /* raise z to integer power */
  401.   dComplex __cmf  ln(  dComplex __z );
  402.   dComplex __cmf  log(  dComplex __z );  /* sane as ln */
  403.   dComplex __cmf  log2( dComplex __z );
  404.   dComplex __cmf  log10( dComplex __z );
  405.   dComplex __cmf  pow( dComplex __z, dComplex __exponent );
  406.   dComplex __cmf  pow( dComplex __z,  double __exponent ); // identical to powReExpo
  407.   dComplex __cmf  pow( double __base,  dComplex __exponent ); // identical to powReBase
  408.   dComplex __cmf  powReBase( double __base, dComplex __exponent ); // power of real base
  409.   dComplex __cmf  powReExpo( dComplex __z, double __exponent );    // raise z to real power
  410.                             // for integer exponents, use ipow !
  411.   dComplex __cmf  quartic( dComplex __z );  // raise to the fourth power
  412.   dComplex __cmf  sin(  dComplex __z );
  413.   dComplex __cmf  sinh( dComplex __z );
  414.   dComplex __cmf  square( dComplex __z );
  415.   dComplex __cmf  sqrt( dComplex __z );
  416.   dComplex __cmf  tan(  dComplex __z );
  417.   dComplex __cmf  tanh( dComplex __z );
  418. #endif // __STD_COMPLEX , __COMPLEX_H, __NEWCPLX_H
  419.  
  420. extern "C" {
  421. #endif  /* __cplusplus  */
  422.  
  423. /***  user-accessible error handling functions, borrowed from VectorLib  ****/
  424.  
  425. void  __cmf  V_noteError( char _VFAR *fname, unsigned why );
  426. void  __cmf  V_printErrorMsg( char _VFAR *ErrMsg );
  427. void  __cmf  V_setErrorEventFile( char _VFAR *filename,  unsigned ScreenAndFile );
  428. void  __cmf  V_closeErrorEventFile( void );
  429.  
  430. /*** translation of calls to matherr() into _matherr() for BorlandC 4.0+ ***/
  431.  
  432. #if (__BORLANDC__ >= 0x450) && !defined (__FLAT__)
  433.      #if !defined( __MATH_H )
  434.             #include <math.h>
  435.      #endif
  436.      int  _Cdecl _FARFUNC matherr (struct exception _VFAR *__e);
  437.      #define NEWMATHERR  \
  438.          int matherr( struct exception _VFAR *__e ) \
  439.          {  return( _matherr( __e )); }
  440. #else
  441.      #define NEWMATHERR
  442. #endif
  443.  
  444. #ifdef __cplusplus
  445. }   // end of extern "C"
  446. #endif
  447. #endif   /*  __CDMATH_H  */
  448.